package com.jiadakeji.ppm.modules.invoice.web;

import com.jiadakeji.ppm.api.common.JsonResult;
import com.jiadakeji.ppm.common.utils.*;
import com.jiadakeji.ppm.common.web.BaseController;
import com.jiadakeji.ppm.modules.business.dao.TaxRateDao;
import com.jiadakeji.ppm.modules.business.entity.FeeCharge;
import com.jiadakeji.ppm.modules.business.entity.FeeReceive;
import com.jiadakeji.ppm.modules.business.entity.TaxRate;
import com.jiadakeji.ppm.modules.business.service.FeeChargeService;
import com.jiadakeji.ppm.modules.business.service.FeeReceiveService;
import com.jiadakeji.ppm.modules.invoice.entity.*;
import com.jiadakeji.ppm.modules.invoice.service.CounterService;
import com.jiadakeji.ppm.modules.invoice.service.FillingInvoiceService;
import com.jiadakeji.ppm.modules.sys.utils.UserUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;
import java.util.stream.Collectors;

@Controller
@RequestMapping("${adminPath}/invioce")
public class FillingInvioceController extends BaseController {

    @Autowired
    private FillingInvoiceService fillingInvoiceService;
    @Autowired
    private FeeChargeService feeChargeService;
    @Autowired
    private FeeReceiveService feeReceiveService;
    @Autowired
    private CounterService counterService;
    @Autowired
    private TaxRateDao taxRateDao;

    private Logger logger = LoggerFactory.getLogger(FillingInvioceController.class);
    private String invioceAddr = "http://124.225.17.145:8082/SKServer/SKDo";
    
    private final static String COUNTER = "xy001";

    /**
     * 电费发票
     * @param receiveId
     * @param model
     * @return
     */
    @RequiresPermissions("invioce:preInvioce")
    @RequestMapping("preInvioce")
    public String preInvioce(String receiveId, Model model){
        String counter = COUNTER;
        FeeReceive feeReceive = feeReceiveService.get(receiveId);
        FeeCharge feeCharge = feeChargeService.get(feeReceive.getFeeChargeId());
        Map<String, String> map = InvoiceUtils.getPreData();
        List<Goods> list = fillingInvoiceService.setGoods(feeCharge,feeReceive, new SalesGoods());
        Content content2 = fillingInvoiceService.setFeeContent(feeReceive,feeCharge,list);
        try {
            String moneySum = MoneyChangeUtils.digitUppercase(String.valueOf(content2.getJshj()));
            model.addAttribute("moneySum",moneySum);
        } catch (Exception e) {
            e.printStackTrace();
        }
        FillingInvoice fillingInvoice = new FillingInvoice();
        fillingInvoice.setContent(content2);
        model.addAttribute("preContent", content2);         //发票预填充信息主体
        model.addAttribute("goodsList", list);              //商品信息
        model.addAttribute("map", map);                     //销货方信息
        model.addAttribute("counter",counter);              //柜台号
        model.addAttribute("feeCharge",feeCharge);
        model.addAttribute("feeReceive", feeReceive);
        model.addAttribute("fillInvioce",fillingInvoice);
        model.addAttribute("chargeType","elec");            //用于发票打印后的操作员处理
        return "modules/invioce/invioce";
    }
    /*

    */




    @ResponseBody
    @RequestMapping("filling")      //发票开具，制作xml
    public String filling(FillingInvoice fillingInvoice, String settleId){

       // fillingInvoiceService.updateSettleUser(fillingInvoice, settleId);
        SalesGoods salesGoods = fillingInvoice.getContent().getSalesGoods();
        for(Goods temp : salesGoods.getGroup()){
            if(temp.getSpmc().equals("") && temp.getJe() == null && temp.getSe() == null){
                salesGoods.getGroup().remove(temp);
            }
        }
        salesGoods.setCount(salesGoods.getGroup().size());
        String oriXml = XmlUtils.objectToXml(fillingInvoice,"GBK");         //转义解码前             http请求做了一次转义、对象转xml再做一次转义
        String xml = Encodes.unescapeHtml(Encodes.unescapeXml(oriXml));            //转义解码后          所以是两次解码         将特殊字符解码成网页显示的字符
        String allxml = xml.replace("<sl>0.0</sl>","<sl>0</sl>");
        String responseXml = allxml.replace("standalone=\"yes\"","");
        logger.info("发票开具xml"+responseXml);
        return responseXml ;
    }


    @ResponseBody
    @RequestMapping("doPrinter")        //做发票打印的xml
    public Map<String, String> doPrinter(String requestXml, String fplxdm, String kpzdbs){

        requestXml = Encodes.unescapeXml(requestXml);

        logger.info("开具返回结果xml："+requestXml);
        Map<String, String> map = new HashMap<>();
        String xml = "";
        FillingInvoiceResponse fillingInvoiceResponse = (FillingInvoiceResponse) XmlUtils.xmlToObject(FillingInvoiceResponse.class,requestXml);
        map.put("code",fillingInvoiceResponse.getReturnDetail().getReturncode());
        if(fillingInvoiceResponse.getReturnDetail().getReturnData() != null) {
            map.put("fpdm", fillingInvoiceResponse.getReturnDetail().getReturnData().getFpdm());
            map.put("fphm", fillingInvoiceResponse.getReturnDetail().getReturnData().getFphm());

            xml = "<?xml version=\"1.0\" encoding=\"gbk\"?>\n" +
                    "<business id=\"20004\"comment=\"发票打印\">\n" +
                    "<body yylxdm=\"1\">\n" +
                    "<kpzdbs>" + kpzdbs + "</kpzdbs>\n" +
                    "<fplxdm>" + fplxdm + "</fplxdm>\n" +
                    "<fpdm>" + fillingInvoiceResponse.getReturnDetail().getReturnData().getFpdm() + "</fpdm>\n" +
                    "<fphm>" + fillingInvoiceResponse.getReturnDetail().getReturnData().getFphm() + "</fphm>\n" +
                    "<dylx>0</dylx>\n" +
                    "<dyfs>0</dyfs>\n" +
                    "<printername></printername>\n" +
                    "</body>\n" +
                    "</business>";
        }
        logger.info(xml);
        if(! "0".equals(fillingInvoiceResponse.getReturnDetail().getReturncode())){
            xml = requestXml;
        }
        if(StringUtils.isBlank(fplxdm) || StringUtils.isBlank(kpzdbs)){
            xml = requestXml;
        }
        map.put("xml",xml);
        logger.info("发票打印xml"+xml);
        return map;
    }

    @ResponseBody
    @RequestMapping("inviladInvioce")
    public String inviladInvioce(InviladInvioce inviladInvioce){
        String xml = XmlUtils.objectToXml(inviladInvioce,"GBK");
        String responseXml = xml.replace("standalone=\"yes\"","");
        logger.info("发票作废xml"+responseXml);
        return responseXml ;
    }

    @RequiresPermissions("invioce:preInvilad")
    @RequestMapping("preInvilad")        //准备作废
    public String preInvilad(Model model){
        String counter = COUNTER;
        model.addAttribute("inviladInvioce", new InviladInvioce());
        model.addAttribute("counter",counter);
        return "modules/invioce/preInvilad";
    }

    @ResponseBody
    @RequestMapping("getMarginProperty")
    public String getMarginProperty(String fplxdm){
//        String counter = (String) SecurityUtils.getSubject().getSession().getAttribute("counter");
     //   String counterId = (String) SecurityUtils.getSubject().getSession().getAttribute("counterId");
//        Map<String,Map<String,String>> map = BussinessUtil.getMarginByCount();
        Counter temp = counterService.get("1");
        if(temp == null){
            return "";
        }
//        Map<String,String> margin = map.get(counter);
//        String  left = margin.get("007Left");
        String leftCount = temp.getSevenLeft();
//        String top = margin.get("007Top");
        String topCount = temp.getSevenTop();
        if("004".equals(fplxdm)){
//            left = margin.get("004Left");
            leftCount = temp.getFourLeft();
//            top = margin.get("004Top");
            topCount = temp.getFourTop();
        }
        String responseXml = "<?xml version=\"1.0\" encoding=\"gbk\"?>\n" +
                "<business id=\"20003\" comment=\"页边距设置\">\n" +
                "<body yylxdm=\"1\">\n" +
                "<fplxdm>"+"007"+"</fplxdm>\n" +
                "<top>"+topCount+"</top>\n" +
                "<left>"+leftCount+"</left>\n" +
                "</body>\n" +
                "</business>\n";
        logger.info("参数设置xml"+responseXml);
        return responseXml;
    }

    /**
     * 发票查看
     * @param findInvioceCondition
     * @param model
     * @return
     */
    @RequiresPermissions("invioce:invioceSearch")
    @RequestMapping("invioceSearch")
    public String invioceSearch(FindInvioceCondition findInvioceCondition, Model model){
        Date startDate = new Date();
        String fpdm = "", fphm = "";
        if(findInvioceCondition != null && findInvioceCondition.getStartDate() != null){
            startDate = findInvioceCondition.getStartDate();
        }
        String counter = COUNTER;
        String fplxdm = "007",searchType = "1";        //从左往右 发票类型代码 查询方式
        String cxtjDate = DateUtils.formatDateTimeYYYYMMDD(startDate);
        String cxtj = cxtjDate + cxtjDate;              //查询条件
        if(findInvioceCondition != null && findInvioceCondition.getSearchType() != null){
            fplxdm = findInvioceCondition.getFplxdm();
            searchType = findInvioceCondition.getSearchType();
            fphm = findInvioceCondition.getFphm();
            fpdm = findInvioceCondition.getFpdm();
            if("1".equals(searchType)){
                cxtjDate = DateUtils.formatDateTimeYYYYMMDD(findInvioceCondition.getStartDate());
                cxtj = cxtjDate + cxtjDate;
            }else {
                cxtj = fpdm+fphm+fphm;
            }
        }

        findInvioceCondition.setStartDate(DateUtils.parseDate(cxtjDate));
        String requestXml = "<?xml version=\"1.1\" encoding=\"gbk\"?>\n" +
                "<business id=\"10010\" comment=\"发票查询\">\n" +
                "<body yylxdm=\"1\">\n" +
                "<kpzdbs>"+counter+"</kpzdbs>\n" +
                "<fplxdm>"+fplxdm+"</fplxdm>\n" +
                "<cxfs>"+searchType+"</cxfs>\n" +
                "<cxtj>"+cxtj+"</cxtj>\n" +
                "</body>\n" +
                "</business>";

        logger.info("发票查询xml"+requestXml);
        String url = invioceAddr;
        String responseXml = UrlUtils.sendPost(url,requestXml,"GBK");
        SearchReturnData searchReturnData = (SearchReturnData) XmlUtils.xmlToObject(SearchReturnData.class,responseXml);
        List<SearchInvioceInfo> list = new ArrayList<>();
        if(searchReturnData != null && searchReturnData.getSearchInvioceDetail() != null && searchReturnData.getSearchInvioceDetail().getSearchInvioceReturnData()!=null ){
            list = searchReturnData.getSearchInvioceDetail().getSearchInvioceReturnData().getSearchInvioceContent().getSearchInvioceInfoList();
        }
        Double total = 0.0;
        for (SearchInvioceInfo sii:list) {
            total = DecimalUtils.add(Double.valueOf(sii.getJshj()),total);
        }
        model.addAttribute("total",total);
        model.addAttribute("list",list);
        model.addAttribute("counter",counter);
        model.addAttribute("searchInvioce", findInvioceCondition);
        return "modules/invioce/invioceList";
    }

    /**
     * 发票统计
     * @param findInvioceCondition
     * @param kpr
     * @param model
     * @return
     */
    @RequestMapping("invioceStatic")
    public String invioceStatic(FindInvioceCondition findInvioceCondition, @RequestParam(required = false) String kpr, Model model){

        Date startDate = new Date();
        if(findInvioceCondition != null && findInvioceCondition.getStartDate() != null){
            startDate = findInvioceCondition.getStartDate();
        }
        String cxtjDate = DateUtils.formatDateTimeYYYYMMDD(startDate);

        List<SearchInvioceInfo> listList = new ArrayList<>();

        List<SearchInvioceInfo> list = fillingInvoiceService.staticInvioce(findInvioceCondition);
        List<String> kprList = new ArrayList<>();

        if(StringUtils.isBlank(kpr)){       //如果筛选条件（开票人为空则全部成员记录）筛选无重复的开票人名称list
            kprList = list.stream().map(SearchInvioceInfo::getKpr).distinct().collect(Collectors.toList());
        }else {
            kprList.add(kpr);           //如果筛选条件（开票人不为空则只查找改成员记录）
        }
        if(UserUtils.getUser().isAdmin()
                || UserUtils.getUser().getRoleNames().contains("桂林洋管理员")
                || UserUtils.getUser().getRoleNames().contains("出纳员") ){         //管理员进行全员统计
            for(String temp: kprList){
                List<SearchInvioceInfo> kprSearchList = list.stream()
                        .filter(searchInvioceInfo -> searchInvioceInfo.getKpr().equals(temp) && searchInvioceInfo.getFpzt().equals("00")).collect(Collectors.toList());          //筛选这个开票人的开票数据
                SearchInvioceInfo total = new SearchInvioceInfo();          //统计个人总金额
                double hjje = 0.0 , hjse  = 0.0, jshj = 0.0;       //合计金额  合计税额  价税合计
                for (SearchInvioceInfo searchInvioceInfo : kprSearchList){
                    hjje += Double.parseDouble(searchInvioceInfo.getHjje());
                    hjse += Double.parseDouble(searchInvioceInfo.getHjse());
                    jshj += Double.parseDouble(searchInvioceInfo.getJshj());
                }
                total.setHjje(String.valueOf(StringUtils.changeScale(2,hjje)));
                total.setHjse(String.valueOf(StringUtils.changeScale(2,hjse)));
                total.setJshj(String.valueOf(StringUtils.changeScale(2,jshj)));
                total.setGhdwmc(String.valueOf(kprSearchList.size()));
                total.setKpr(temp);
                total.setKprq(cxtjDate);
                listList.add(total);
            }
        }else{              //个人使用单人，单个柜台统计
            List<SearchInvioceInfo> kprSearchList = list.stream().filter(searchInvioceInfo ->
                    searchInvioceInfo.getKpr().equals(UserUtils.getUser().getName()) && searchInvioceInfo.getFpzt().equals("00")).collect(Collectors.toList());          //筛选这个开票人的开票数据
            SearchInvioceInfo total = new SearchInvioceInfo();          //统计个人总金额
            double hjje = 0.0 , hjse  = 0.0, jshj = 0.0;       //合计金额  合计税额  价税合计
            for (SearchInvioceInfo searchInvioceInfo : kprSearchList){

                hjje += Double.parseDouble(searchInvioceInfo.getHjje());
                hjse += Double.parseDouble(searchInvioceInfo.getHjse());
                jshj += Double.parseDouble(searchInvioceInfo.getJshj());

            }
            total.setHjje(String.valueOf(StringUtils.changeScale(2,hjje)));
            total.setHjse(String.valueOf(StringUtils.changeScale(2,hjse)));
            total.setJshj(String.valueOf(StringUtils.changeScale(2,jshj)));
            total.setGhdwmc(String.valueOf(kprSearchList.size()));
            total.setKpr(UserUtils.getUser().getName());
            total.setKprq(cxtjDate);
            listList.add(total);

        }

        model.addAttribute("kpr",kpr);
        model.addAttribute("list",listList);
        model.addAttribute("searchInvioce", findInvioceCondition);
        return "modules/invioce/staticList";
    }

    @RequestMapping("redoPrinter")
    public String preDoPrinter(){
        return "modules/invioce/redoPrinter";
    }

    @ResponseBody
    @RequestMapping("prereDo")
    public String prereDo(String fphm, String fpdm, String fplxdm){
        String counter = COUNTER;
        String xml = "<?xml version=\"1.0\" encoding=\"gbk\"?>\n" +
                "<business id=\"20004\"comment=\"发票打印\">\n" +
                "<body yylxdm=\"1\">\n" +
                "<kpzdbs>"+counter+"</kpzdbs>\n" +
                "<fplxdm>"+fplxdm+"</fplxdm>\n" +
                "<fpdm>"+fpdm+"</fpdm>\n" +
                "<fphm>"+fphm+"</fphm>\n" +
                "<dylx>0</dylx>\n" +
                "<dyfs>0</dyfs>\n" +
                "<printername></printername>\n" +
                "</body>\n" +
                "</business>";

        logger.info("发票补打xml:"+xml);
        return xml;
    }


    @ResponseBody
    @RequestMapping("blankFilling")      //报装发票开具，制作xml
    public String blankFilling(FillingInvoice fillingInvoice, String settleId){
      //  fillingInvoiceService.updateSettleUser(fillingInvoice, settleId);
        SalesGoods salesGoods = fillingInvoice.getContent().getSalesGoods();

//        List<Goods> removeList = new ArrayList<>();
        fillingInvoiceService.updateGoodsRate(salesGoods.getGroup());
        salesGoods.getGroup().removeIf(goods -> goods.getSpbm().equals("") && goods.getSpmc().equals("") && null == goods.getJe() && null == goods.getSe() );       //去除空对象

//        for (Goods temp : salesGoods.getGroup()){
//            if (temp.getSpbm() == "yazfwf") {
//                temp.setSpbm("3050200000000000000");
//            }else if(temp.getSpbm() == "yzlfw") {
//                temp.setSpbm("3040502020400000000");
//            }else if(temp.getSpbm() == "ydf") {
//                temp.setSpbm("1100101020200000000");
//            }
//        }
//
//        for (Goods goods : salesGoods.getGroup()){          //去除空对象
//            if(goods.getSpbm().equals("") && goods.getSpmc().equals("") && null == goods.getJe() && null == goods.getSe() ){
//                removeList.add(goods);
//            }
//        }
//        for(Goods temp :removeList){
//            salesGoods.getGroup().remove(temp);
//        }
        int i =1;
        for (Goods temp : salesGoods.getGroup()){           //重新填写序号
            temp.setXh(String.valueOf(i));
            i ++;
        }
        salesGoods.setCount(salesGoods.getGroup().size());
        String oriXml = XmlUtils.objectToXml(fillingInvoice,"GBK");         //转义解码前             http请求做了一次转义、对象转xml再做一次转义
        String xml = Encodes.unescapeHtml(Encodes.unescapeXml(oriXml));            //转义解码后          所以是两次解码         将特殊字符解码成网页显示的字符
        String allxml = xml.replace("<sl>0.0</sl>","<sl>0</sl>");
        String responseXml = allxml.replace("standalone=\"yes\"","");
        logger.info("发票开具xml"+responseXml);
        return responseXml ;
    }


    @RequiresPermissions("invioce:blankInvioce")
    @RequestMapping("blankInvioce")
    public String blankInvioce(Model model){
        String counter = COUNTER;
        Map<String, String> map = InvoiceUtils.getPreData();
        List<Goods> list = fillingInvoiceService.setBlankGoods();
        Content content = new Content();
        content.setFpqqlsh(IdGen.uuid());
        content.setKpr(UserUtils.getUser().getName());
        content.setSkr("林丹丹");
        content.setFhr("卢芳友");
        content.setFplxdm("007");
        content.setTspz("00");
        FillingInvoice fillingInvoice = new FillingInvoice();
        TaxRate taxRate = new TaxRate();
        List<TaxRate> taxRateList = taxRateDao.findList(taxRate);
        for (TaxRate t:taxRateList) {
           t.setSpName(t.getSpName()+":"+t.getAfterRate());
        }
        fillingInvoice.setContent(content);
        model.addAttribute("preContent", content);
        model.addAttribute("goodsList", list);
        model.addAttribute("map", map);
        model.addAttribute("counter",counter);
        model.addAttribute("fillInvioce",fillingInvoice);
        model.addAttribute("taxRateList",taxRateList);

        //将返回的对象进行处理，对于有内容的对象根据他的税率值（前端传入商品编码）再来设置税率等内容
        return  "modules/invioce/invioceNoForEach";
    }

    @RequestMapping("test")
    public String test(Model model){
        String counter = COUNTER;
        Map<String, String> map = InvoiceUtils.getPreData();
        List<Goods> list = fillingInvoiceService.setBlankGoods();
        Content content = new Content();
        content.setKpr(UserUtils.getUser().getName());
        content.setSkr("林丹丹");
        content.setFhr("卢芳友");
        content.setFplxdm("007");
        content.setTspz("00");
        FillingInvoice fillingInvoice = new FillingInvoice();
        fillingInvoice.setContent(content);
        model.addAttribute("preContent", content);
        model.addAttribute("goodsList", list);
        model.addAttribute("map", map);
        model.addAttribute("counter",counter);
        model.addAttribute("fillInvioce",fillingInvoice);
        return "modules/reports/ELecRecycle";

    }

    @ResponseBody
    @RequestMapping("updateReceive")
    public JsonResult<String> updateReceive(String chargeType, String receiveId){
        JsonResult<String> jsonResult = new JsonResult<>();
        if(StringUtils.isBlank(chargeType)||StringUtils.isBlank(receiveId)){
            jsonResult.setCode(-1);
            jsonResult.setMessage("chargeType 或 receiveId 为空，更新失败");
            return jsonResult;
        }
            FeeReceive feeReceive = feeReceiveService.get(receiveId);
            feeReceive.setOperatorId(UserUtils.getUser().getId());
            feeReceiveService.save(feeReceive);
            jsonResult.setMessage("更新收费"+receiveId+"成功");
            return jsonResult;


    }
}
